package DGWeb.Servlets;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.tomcat.dbcp.dbcp.BasicDataSource;

import DGWeb.AppConstants;
import DGWeb.Model.Follower;
import DGWeb.Model.User;

import com.google.gson.Gson;

/**
 * Servlet implementation class getFollowings
 */
@WebServlet("/getFollowings")
public class getFollowings extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public getFollowings() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession UserSession = request.getSession();
		String current_user = (String) UserSession.getAttribute("Username");
		Context context = null;
		BasicDataSource ds = null;
		Connection conn = null;
		Statement stmt = null;
		java.sql.ResultSet res = null;
		try 
		{
			PrintWriter out = response.getWriter();
			// extract data from Json
			InputStreamReader isr = new InputStreamReader(request.getInputStream());
			BufferedReader br = new BufferedReader(isr);
			StringBuilder jsonFileContent = new StringBuilder();
			//read the only line
			jsonFileContent.append( br.readLine());
			//String[] DataArray = jsonFileContent.toString().split(":");
			Gson gson = new Gson();
			User user = gson.fromJson(jsonFileContent.toString(),User.class );
			String exec = AppConstants.GET_FOLLOWINGS_WITH_DETAILS.replaceAll("//", user.getUsername());
			//Collection<Follower> FollowingResult = (Collection<Follower>)getServletContext().getAttribute(AppConstants.FOLLOWER_TABLE);
			Collection<Follower> temp = new ArrayList<Follower>();

			
			context = new InitialContext();
			ds = (BasicDataSource)context.lookup(AppConstants.DB_DATASOURCE);
			conn = ds.getConnection();
			stmt = conn.createStatement();
			res = stmt.executeQuery(exec);

			String following_username = null;
			String following_nickname = null;	
			String following_photo = null;
			String following_description = null;
			Boolean enable_follow_button = false;
			Boolean enable_unfollow_button = false;
			while (res.next() ){
				following_username = res.getString(AppConstants.USERNAME);
				following_nickname = res.getString(AppConstants.NICKNAME);
				following_photo = res.getString(AppConstants.PHOTO);
				following_description = res.getString(AppConstants.DESCRIPTION);
				Boolean is_curr_user_follow_the_following = getMessages.CheckIfWeFollowed(current_user, following_username);
				if (following_username.equals(current_user)){
					enable_follow_button = false;
					enable_unfollow_button = false;
				}
				else if (is_curr_user_follow_the_following){
					enable_unfollow_button=true;
					enable_follow_button = false;
				}
				else{
					enable_unfollow_button=false;
					enable_follow_button = true;
				}
				Follower following = new Follower(following_username, following_nickname, following_photo, following_description, enable_follow_button, enable_unfollow_button, 0, 0);
				temp.add(following);
			}
			

			//get 10 top "popular" followers (using the formula: log(2 + #follower)
			//first- we calculate the formula for each follower
			Collection<Follower> temp2=new ArrayList<Follower>();
			for (Follower following : temp){
				exec = AppConstants.COUNT_FOLLOWERS.replaceAll("//", following.getUsername());
				stmt = conn.createStatement();
				res = stmt.executeQuery(exec);
				while (res.next() ){
					following.setNumOfFollowers(res.getInt("num_of_followers"));
					double popularity =  Math.log( 2 + res.getInt("num_of_followers"));
					following.setPopularity(popularity);
					temp2.add(following);
				}
			}
			//then- we arrange them in a descending order
			List<Follower> followings_list = new ArrayList<Follower>(temp2);
			sort_by_popularity(followings_list);
			
			//, and filter out if there are more than 10 followers.
			List<Follower> followings_list_filtered = new ArrayList<Follower>();
			if(followings_list.size() > 10){
				followings_list_filtered = followings_list.subList(0, 10) ;
			}
			else followings_list_filtered = followings_list;
			
			//FollowerResult = followers_list;
			gson = new Gson();
			String FollowingJsonResult = gson.toJson(followings_list_filtered, AppConstants.USERS_COLLECTION);
			out.println(FollowingJsonResult);



			//Release
			res.close();
			conn.commit();
			stmt.close();
			conn.close();
			context.close();
    		
    		
			
		}catch (NamingException |SQLException e){
			try {
			if (stmt != null)
				stmt.close();
			if (context != null)
				context.close();
			if ( conn != null )
				conn.close();
			if ( res != null )
				res.close();
			} catch (SQLException | NamingException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}

	public void sort_by_popularity(List<Follower> followings_list) {
	    Comparator<Follower> comparator;
	    comparator = idComparator;
	    Collections.sort(followings_list, comparator);
	}
	
	
	Comparator<Follower> idComparator = new Comparator<Follower>() {
	    @Override
	    public int compare(Follower f1, Follower f2) {
	        return Double.compare(f2.getPopularity(), f1.getPopularity());
	    }
	};

}
